package org.as4game.resource.buffer
{
	import flash.display3D.Context3D;
	import flash.display3D.Context3DVertexBufferFormat;
	import flash.display3D.VertexBuffer3D;
	
	import org.as4game.common.utils.VertexFormatTool;
	import org.as4game.resource.manager.IResource;

	/**
	 * 顶点缓冲区
	 */
	public class VertexBuffer implements IResource
	{
		private var _vertexFormat:String;			// 顶点格式, Context3DVertexBufferFormat.FLOAT_x 			
		private var _vertexSize:uint;				// 每顶点字节数
		private var _vertexCount:uint;				// 顶点个数
		private var _mem_buffer:Vector.<Number>;	// 内存缓存
		private var _card_buffer:VertexBuffer3D;	// 显卡缓存
		
		
		public function VertexBuffer(){
		}
		
		/**
		 * 构造缓冲区
		 * @param vertexCount 顶点个数
		 * @param size 每顶点字节数
		 * @param fmt 顶点格式, 2个参数中必须有1个有值
		 * @param buf 现有的数据
		 */
		public function create(vertexCount:uint, size:int, fmt:String=null, buf:Vector.<Number>=null):void{
			if( size ) fmt = VertexFormatTool.size2format( size );
			else if( fmt ) size = VertexFormatTool.format2size( fmt );
			if(!size && !fmt){
				throw new Error("非法的顶点格式");
			}
			_vertexFormat = fmt;
			_vertexSize = size;
			_vertexCount = vertexCount;
			_mem_buffer = buf || new Vector.<Number>( vertexCount );
		}
		
		/**
		 * 获取顶点格式
		 */
		public function get vertexFormat():String{
			return _vertexFormat;
		}
		public function get vertexSize():int{
			return _vertexSize;
		}
		
		/**
		 * 获取顶点个数
		 */
		public function get vertexCount():uint{
			return _vertexCount;
		}
		
		/**
		 * 获取内存缓存
		 */
		public function getMemoryBuffer():Vector.<Number>{
			return _mem_buffer;
		}
		
		/**
		 * 获取显卡缓存
		 */
		public function getCardBuffer( context3D:Context3D ):VertexBuffer3D{
			if( _mem_buffer ){
				if( _card_buffer ){
					_card_buffer.dispose();
				}
				_card_buffer = context3D.createVertexBuffer( _vertexCount, _vertexSize / 4 );
				_card_buffer.uploadFromVector( _mem_buffer, 0, _vertexCount );
				_mem_buffer = null;
			}
			return _card_buffer;
		}
		
		/**
		 * @inheritDoc
		 */
		public function dispose():void{
			_vertexFormat = null;
			_vertexSize = 0;
			_vertexCount = 0;
			_mem_buffer = null;
			if( _card_buffer ){
				_card_buffer.dispose();
				_card_buffer = null;
			}
		}
		
		/**
		 * @inheritDoc
		 */
		public function get totalMemory():uint{
			return _vertexSize * _vertexCount;
		}
	}
}